/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ee.persistence;

import java.util.HashMap;
import java.util.List;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import org.ee.persistence.exception.NotFoundException;
import org.ee.persistence.exception.NotUniqueException;

/**
 *
 * @author Gabriel Bran <gbran.u@gmail.com>
 */
public abstract class AbstractQueryModel extends AbstractTemplate {

    public Object[] nativeQueryResult(String sqlQuery, List<Object> parameters) throws NotFoundException, NotUniqueException {
        try {
            Query query = getEntityManager().createNativeQuery(sqlQuery);
            return (Object[]) setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public Object[] nativeQueryResult(String sqlQuery, HashMap<Integer, Object> parameters) throws NotFoundException, NotUniqueException {
        try {
            Query query = getEntityManager().createNativeQuery(sqlQuery);
            return (Object[]) setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public <T> T nativeQueryResult(String sqlQuery, HashMap<Integer, Object> parameters, Class<T> resultClass) throws NotFoundException, NotUniqueException {
        try {
            Query query = getEntityManager().createNativeQuery(sqlQuery, resultClass);
            return (T) setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public <T> List<T> nativeQuery(String sqlQuery, HashMap<Integer, Object> parameters, Class<T> resultClass) {
        Query query = getEntityManager().createNativeQuery(sqlQuery, resultClass);
        return setQueryParameters(query, parameters).getResultList();
    }

    public <T> List<T> nativeQuery(String sqlQuery, HashMap<Integer, Object> parameters, Class<T> resultClass, int firstResult, int maxResult) {
        Query query = getEntityManager().createNativeQuery(sqlQuery, resultClass);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public List<Object[]> nativeQuery(String sqlQuery, HashMap<Integer, Object> parameters) {
        Query query = getEntityManager().createNativeQuery(sqlQuery);
        return setQueryParameters(query, parameters).getResultList();
    }

    public List<Object[]> nativeQuery(String sqlQuery, HashMap<Integer, Object> parameters, int firstResult, int maxResult) {
        Query query = getEntityManager().createNativeQuery(sqlQuery);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public <T> T namedNativeQueryResult(String queryName, HashMap<Integer, Object> parameters, Class<T> resultClass) throws NotFoundException, NotUniqueException {
        try {
            TypedQuery<T> query = getEntityManager().createNamedQuery(queryName, resultClass);
            return setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public Object[] namedNativeQueryResult(String queryName, List<Object> parameters) throws NotFoundException, NotUniqueException {
        try {
            Query query = getEntityManager().createNamedQuery(queryName);
            return (Object[]) setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public Object[] namedNativeQueryResult(String queryName, HashMap<Integer, Object> parameters) throws NotFoundException, NotUniqueException {
        try {
            Query query = getEntityManager().createNamedQuery(queryName);
            return (Object[]) setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public List<Object[]> namedNativeQuery(String queryName, HashMap<Integer, Object> parameters) {
        Query query = getEntityManager().createNamedQuery(queryName);
        return setQueryParameters(query, parameters).getResultList();
    }

    public <T> List<T> namedNativeQuery(String queryName, HashMap<Integer, Object> parameters, Class<T> resultClass) {
        TypedQuery<T> query = getEntityManager().createNamedQuery(queryName, resultClass);
        return setQueryParameters(query, parameters).getResultList();
    }

    public List<Object[]> namedNativeQuery(String queryName, HashMap<Integer, Object> parameters, int firstResult, int maxResult) {
        Query query = getEntityManager().createNamedQuery(queryName);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public <T> List<T> namedNativeQuery(String queryName, HashMap<Integer, Object> parameters, Class<T> resultClass, int firstResult, int maxResult) {
        TypedQuery<T> query = getEntityManager().createNamedQuery(queryName, resultClass);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public void namedNativeQueryUpdate(String queryName, HashMap<Integer, Object> parameters) {
        Query query = getEntityManager().createNamedQuery(queryName);
        query = setQueryParameters(query, parameters);
        query.executeUpdate();
    }

    public <T> T namedQueryResult(String queryName, HashMap<String, Object> parameters, Class<T> resultClass) throws NotFoundException, NotUniqueException {
        try {
            TypedQuery<T> query = getEntityManager().createNamedQuery(queryName, resultClass);
            return setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public <T> List<T> namedQuery(String queryName, HashMap<String, Object> parameters, Class<T> resultClass) {
        TypedQuery<T> query = getEntityManager().createNamedQuery(queryName, resultClass);
        return setQueryParameters(query, parameters).getResultList();
    }

    public <T> List<T> namedQuery(String queryName, HashMap<String, Object> parameters) {
        Query query = getEntityManager().createNamedQuery(queryName);
        return setQueryParameters(query, parameters).getResultList();
    }

    public <T> List<T> namedQuery(String queryName, HashMap<String, Object> parameters, int firstResult, int maxResult) {
        Query query = getEntityManager().createNamedQuery(queryName);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public <T> List<T> namedQuery(String queryName, HashMap<String, Object> parameters, Class<T> resultClass, int firstResult, int maxResult) {
        TypedQuery<T> query = getEntityManager().createNamedQuery(queryName, resultClass);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public <T> T jpqlResult(String jpqlQuery, HashMap<String, Object> parameters, Class<T> resultClass) throws NotFoundException, NotUniqueException {
        try {
            TypedQuery<T> query = getEntityManager().createQuery(jpqlQuery, resultClass);
            return setQueryParameters(query, parameters).getSingleResult();
        } catch (NoResultException e) {
            throw new NotFoundException(e);
        } catch (NonUniqueResultException e) {
            throw new NotUniqueException(e);
        }
    }

    public <T> List<T> jpqlQuery(String jpqlQuery, HashMap<String, Object> parameters) {
        Query query = getEntityManager().createQuery(jpqlQuery);
        return setQueryParameters(query, parameters).getResultList();
    }

    public <T> List<T> jpqlQuery(String jpqlQuery, HashMap<String, Object> parameters, int firstResult, int maxResult) {
        Query query = getEntityManager().createQuery(jpqlQuery);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }

    public <T> List<T> jpqlQuery(String jpqlQuery, HashMap<String, Object> parameters, Class<T> resultClass) {
        TypedQuery<T> query = getEntityManager().createQuery(jpqlQuery, resultClass);
        return setQueryParameters(query, parameters).getResultList();
    }

    public <T> List<T> jpqlQuery(String jpqlQuery, HashMap<String, Object> parameters, Class<T> resultClass, int firstResult, int maxResult) {
        TypedQuery<T> query = getEntityManager().createQuery(jpqlQuery, resultClass);
        return setQueryParameters(query, parameters, firstResult, maxResult).getResultList();
    }
}
